🚀 Bài 9: JavaScript typeof, toString(), Type Conversion, Destructuring, Bitwise

Các thao tác và chuyển đổi kiểu dữ liệu trong JavaScript

← Quay lại trang chính

1. 🔍 JavaScript typeof

typeof là toán tử dùng để kiểm tra kiểu dữ liệu của một biến hoặc giá trị.

typeof-example.js
console.log(typeof 123); // "number"
console.log(typeof "Hello"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (đây là bug lịch sử)
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof function(){}); // "function"

🎮 Thử ngay: typeof

2. 🔄 JavaScript toString()

toString() là method chuyển giá trị về dạng chuỗi. Hầu hết các kiểu dữ liệu trong JavaScript đều có phương thức toString().

✅ Những kiểu dữ liệu CÓ toString():

  • Number: 123.toString()"123"
  • Boolean: true.toString()"true"
  • Array: [1,2,3].toString()"1,2,3"
  • Object: {}.toString()"[object Object]"
  • Function: function(){}.toString() → trả về source code
  • Date: new Date().toString()"Mon Jul 15 2025..."
  • RegExp: /abc/g.toString()"/abc/g"

⚠️ Những giá trị KHÔNG có toString():

  • null: null.toString()TypeError
  • undefined: undefined.toString()TypeError

Giải pháp: Sử dụng String(value) thay vì value.toString() để an toàn hơn.

tostring-detailed.js
// ✅ Number có toString()
const num = 123;
console.log(num.toString()); // "123"
console.log((42).toString()); // "42" (cần dấu ngoặc)

// ✅ Boolean có toString()
const bool = true;
console.log(bool.toString()); // "true"
console.log(false.toString()); // "false"

// ✅ Array có toString()
const arr = [1, 2, 3];
console.log(arr.toString()); // "1,2,3"
console.log([].toString()); // "" (chuỗi rỗng)

// ✅ Object có toString()
const obj = {name: "Long", age: 25};
console.log(obj.toString()); // "[object Object]"

// ✅ Function có toString()
function greet() { return "Hello"; }
console.log(greet.toString()); // "function greet() { return \"Hello\"; }"

// ✅ Date có toString()
const date = new Date();
console.log(date.toString()); // "Mon Jul 15 2025 10:30:00 GMT+0700"

// ⚠️ null và undefined KHÔNG có toString()
// console.log(null.toString()); // TypeError!
// console.log(undefined.toString()); // TypeError!

// 🔧 Giải pháp an toàn: dùng String()
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"

💡 toString() vs String() - Khác biệt quan trọng:

  • value.toString(): Gọi method toString() của object (có thể lỗi với null/undefined)
  • String(value): Chuyển đổi an toàn, không bao giờ lỗi
  • value + "": Cách nhanh để chuyển sang string (type coercion)

🎮 Thử ngay: toString() với các kiểu dữ liệu

3. 🔁 JavaScript Type Conversion

JavaScript tự động chuyển đổi kiểu dữ liệu (type coercion) hoặc bạn có thể chuyển đổi thủ công:

type-conversion.js
// Chuyển sang số
console.log(Number("123")); // 123
console.log(parseInt("456")); // 456
console.log(parseFloat("3.14")); // 3.14

// Chuyển sang chuỗi
console.log(String(789)); // "789"

// Chuyển sang boolean
console.log(Boolean(0)); // false
console.log(Boolean("Hello")); // true

// Tự động chuyển đổi khi so sánh
console.log("5" == 5); // true
console.log("5" === 5); // false

🎮 Thử ngay: Type Conversion

4. 🧩 JavaScript Destructuring

Destructuring là cú pháp giúp "giải nén" giá trị từ array hoặc object vào biến riêng biệt.

destructuring.js
// Array destructuring
const arr = [1, 2, 3];
const [a, b, c] = arr;
console.log(a, b, c); // 1 2 3

// Object destructuring
const obj = {name: "Long", age: 25};
const {name, age} = obj;
console.log(name, age); // "Long" 25

// Đổi tên biến khi destructuring
const {name: fullName} = obj;
console.log(fullName); // "Long"

🎮 Thử ngay: Destructuring

5. ⚡ JavaScript Bitwise Operations

Bitwise là các phép toán thao tác trực tiếp trên các bit của số nguyên. JavaScript chuyển số về dạng 32-bit signed integer trước khi thực hiện phép toán bitwise.

💡 Hiểu về Binary (Hệ nhị phân):

Mỗi số được biểu diễn bằng các bit (0 hoặc 1). Ví dụ:

  • 5 = 101 (binary) = 1×2² + 0×2¹ + 1×2⁰
  • 3 = 011 (binary) = 0×2² + 1×2¹ + 1×2⁰
  • 7 = 111 (binary) = 1×2² + 1×2¹ + 1×2⁰

🔢 Các phép toán Bitwise cơ bản:

🔗 AND (&)

Trả về 1 nếu cả hai bit đều là 1

5 & 3:
  101 (5)
& 011 (3)
-----
  001 (1)
🔀 OR (|)

Trả về 1 nếu ít nhất một bit là 1

5 | 3:
  101 (5)
| 011 (3)
-----
  111 (7)
⚡ XOR (^)

Trả về 1 nếu chỉ một bit là 1

5 ^ 3:
  101 (5)
^ 011 (3)
-----
  110 (6)
🔄 NOT (~)

Đảo ngược tất cả bit (0→1, 1→0)

~5:
101 → 11111...11010
(32-bit signed)
= -6
⬅️ Left Shift (<<)

Dịch tất cả bit sang trái n vị trí, thêm 0 vào bên phải

5 << 1:
101 → 1010
(5 × 2¹ = 10)

5 << 2:
101 → 10100
(5 × 2² = 20)
Công thức: n << k = n × 2ᵏ
Ứng dụng: Nhân nhanh với lũy thừa của 2
➡️ Right Shift (>>)

Dịch bit sang phải (chia cho 2ⁿ)

5 >> 1:
101 → 10
(5 ÷ 2¹ = 2)

⬅️ Chi tiết về Left Shift (<<) - Dịch bit sang trái

🔍 Cách hoạt động:

Left Shift dịch chuyển tất cả các bit sang trái một số vị trí nhất định và điền số 0 vào các vị trí trống bên phải.

Ví dụ chi tiết với số 5:
5 trong binary: 00000101 (8-bit)
5 << 1: 00001010 = 10
5 << 2: 00010100 = 20
5 << 3: 00101000 = 40
5 << 4: 01010000 = 80
📐 Công thức toán học:
n << k = n × 2ᵏ
• k = số vị trí dịch chuyển
• Mỗi lần dịch trái = nhân với 2
• Dịch k lần = nhân với 2ᵏ
📊 Bảng ví dụ thực tế:
Số gốc Phép toán Binary trước Binary sau Kết quả
3 3 << 1 011 110 6
7 7 << 2 0111 11100 28
1 1 << 4 0001 10000 16
🚀 Ứng dụng thực tế:
💨 Nhân nhanh với 2ⁿ
x * 4 = x << 2
x * 8 = x << 3
x * 16 = x << 4
Nhanh hơn phép nhân thông thường
🎮 Game Programming
tileSize = 32
x = tileIndex << 5
// = tileIndex * 32
Tính toán vị trí sprite nhanh
🔢 Tạo lũy thừa của 2
powerOf2 = 1 << n
// 1<<3 = 8, 1<<4 = 16
Tạo các giá trị 2ⁿ một cách hiệu quả
🏴 Bit Flags
READ = 1 << 0 // 1
WRITE = 1 << 1 // 2
EXEC = 1 << 2 // 4
Tạo flags độc lập cho permissions
⚠️ Lưu ý quan trọng:
  • Overflow: Khi dịch quá nhiều, bit sẽ "tràn" ra ngoài 32-bit
  • Số âm: Left shift với số âm có thể cho kết quả không mong muốn
  • Giới hạn: JavaScript sử dụng 32-bit signed integer cho bitwise
  • Performance: Left shift nhanh hơn phép nhân, nhưng chỉ với lũy thừa của 2
🧮 So sánh hiệu suất:
Phép toán thông thường: x * 8 (chậm hơn)
Left shift: x << 3 (nhanh hơn)
Kết quả: Giống nhau (với lũy thừa của 2)

6. 📝 Bài tập thực hành

1. typeof & toString()

  • Viết hàm kiểm tra kiểu dữ liệu của một biến và trả về chuỗi mô tả.
  • Viết hàm chuyển mọi giá trị về chuỗi an toàn (không lỗi với null/undefined).

2. Type Conversion

  • Viết hàm chuyển đổi một chuỗi sang số, boolean, và ngược lại.
  • Kiểm tra kết quả khi chuyển đổi các giá trị đặc biệt: "0", "", null, undefined.

3. Destructuring

  • Giải nén giá trị từ một array và một object bất kỳ.
  • Đổi tên biến khi destructuring object.

4. Bitwise

  • Viết hàm kiểm tra số chẵn/lẻ bằng Bitwise.
  • Viết hàm nhân/chia nhanh với 2 bằng Bitwise.
  • Ứng dụng Left Shift để tạo lũy thừa của 2.
💡 Hãy thử code trực tiếp các bài tập trên để hiểu sâu hơn về lý thuyết!